import threading
import time
import random
from collections import deque
import json

class SimulatedCANBus:
    """
    模拟CAN总线服务，用于生成特种车辆数据
    """
    def __init__(self):
        self.running = False
        self.thread = None
        self.messages = deque()
        self.subscribers = []
        
    def start(self):
        """
        启动模拟CAN总线服务
        """
        if not self.running:
            self.running = True
            self.thread = threading.Thread(target=self._generate_data, daemon=True)
            self.thread.start()
            print("模拟CAN总线服务已启动")
            return True
        else:
            print("模拟CAN总线服务已在运行")
            return False
            
    def stop(self):
        """
        停止模拟CAN总线服务
        """
        self.running = False
        if self.thread:
            self.thread.join()
        print("模拟CAN总线服务已停止")
        
    def subscribe(self, callback):
        """
        订阅CAN消息
        """
        self.subscribers.append(callback)
        
    def unsubscribe(self, callback):
        """
        取消订阅CAN消息
        """
        if callback in self.subscribers:
            self.subscribers.remove(callback)
            
    def get_messages(self, count=10):
        """
        获取最近的CAN消息
        """
        messages = []
        for i in range(min(count, len(self.messages))):
            messages.append(self.messages[i])
        return messages
        
    def _generate_data(self):
        """
        生成特种车辆CAN数据
        """
        vehicle_id = 0x100  # 特种车辆ID
        counter = 0
        
        while self.running:
            # 生成特种车辆数据
            timestamp = time.time()
            
            # 随机生成车辆状态数据
            engine_temp = random.randint(80, 120)  # 发动机温度 (摄氏度)
            oil_pressure = random.randint(30, 80)  # 机油压力 (psi)
            fuel_level = random.randint(0, 100)    # 燃油液位 (%)
            battery_voltage = random.uniform(11.5, 14.5)  # 电池电压 (V)
            speed = random.randint(0, 120)         # 车速 (km/h)
            rpm = random.randint(800, 4000)        # 发动机转速 (RPM)
            gear_position = random.randint(0, 6)   # 档位位置
            brake_status = random.choice([0, 1])   # 刹车状态 (0=未刹车, 1=刹车)
            
            # 构造CAN消息
            message = {
                'timestamp': timestamp,
                'arbitration_id': vehicle_id,
                'data': [
                    engine_temp & 0xFF,
                    oil_pressure & 0xFF,
                    fuel_level & 0xFF,
                    int(battery_voltage * 10) & 0xFF,
                    speed & 0xFF,
                    (rpm >> 8) & 0xFF,  # RPM高字节
                    rpm & 0xFF,         # RPM低字节
                    (gear_position << 4) | (brake_status & 0x0F)
                ],
                'dlc': 8,
                'is_extended_id': False
            }
            
            # 存储消息
            self.messages.appendleft(message)
            if len(self.messages) > 1000:  # 限制消息队列长度
                self.messages.pop()
                
            # 通知订阅者
            for callback in self.subscribers:
                try:
                    callback(message)
                except Exception as e:
                    print(f"订阅者回调错误: {e}")
            
            # 打印消息
            print(f"生成特种车辆数据: ID=0x{message['arbitration_id']:03X}, "
                  f"发动机温度={engine_temp}°C, 机油压力={oil_pressure}psi, "
                  f"燃油={fuel_level}%, 电压={battery_voltage:.1f}V, "
                  f"车速={speed}km/h, 转速={rpm}RPM, 档位={gear_position}, 刹车={'是' if brake_status else '否'}")
            
            # 增加计数器和车辆ID（模拟多辆车）
            counter += 1
            if counter % 50 == 0:  # 每50条消息改变一次车辆ID
                vehicle_id = 0x100 + (counter // 50) % 5
                
            time.sleep(1)  # 每秒生成一条消息

# 全局模拟CAN总线实例
simulated_can_bus = SimulatedCANBus()

def start_simulated_can_bus():
    """
    启动模拟CAN总线服务
    """
    return simulated_can_bus.start()

def stop_simulated_can_bus():
    """
    停止模拟CAN总线服务
    """
    simulated_can_bus.stop()

def get_recent_messages(count=10):
    """
    获取最近的CAN消息
    """
    return simulated_can_bus.get_messages(count)

def subscribe_to_messages(callback):
    """
    订阅CAN消息
    """
    simulated_can_bus.subscribe(callback)

def unsubscribe_from_messages(callback):
    """
    取消订阅CAN消息
    """
    simulated_can_bus.unsubscribe(callback)

if __name__ == "__main__":
    # 启动模拟CAN总线服务
    start_simulated_can_bus()
    
    try:
        # 保持主线程运行
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        # 停止服务
        stop_simulated_can_bus()